using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace EscapeFromLenovo
{
    /// <summary>
    /// The primary class for the game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteManager spriteManager;
        /// <summary>
        /// Elapsed Game Time
        /// </summary>
        TimeSpan myGameTime;
        
        //TILE STUFF
        List<Texture2D> tileTextures = new List<Texture2D>();
        Vector2 bLoc = new Vector2(300, 300);
        Vector2 pLoc = new Vector2(300, 300);
        Vector2 pSpeed = new Vector2(100, 100);
        int boardMove = 0;

        tMaps bacMap = new tMaps(new int[,]
		{
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 1, 2, 1, 4, 3, 1, 5, 1, 2, 2, 1, 3, 4, 1, 5, 2, 1, 1, 4, 4, 3, 1, 5, 1, 4, 1, 2, 5 },
            { 4, 1, 3, 1, 1, 5, 2, 4, 4, 3, 5, 1, 1, 4, 3, 3, 2, 4, 5, 3, 2, 2, 1, 4, 3, 2, 3, 1 },
		}, 28, 12, 64, 64);

        tMaps obMap = new tMaps(new int[,]
		{
			{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
			{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, 6, 6, 6, 6, 6, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7 },
            { -1, 6, 6, 6, 6, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		}, 28, 12, 64, 64);

        tMaps miniMap = new tMaps(new int[,]
		{
            
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },	
			{ -1, -1, -1, -1, 6, 6, 6, 6, 6, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
			{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  },
			{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7  },
			{ -1, 6, 6, 6, 6, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
            { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
		}, 28, 12, 8, 8);

        //SPLASH SCREENS
        Texture2D startscreen;
        Texture2D slider;
        Vector2 sliderpos = new Vector2(668, 195);
        Texture2D helpscreen;
        Texture2D gameoverscreen;
        Texture2D slider2;
        Vector2 slider2pos = new Vector2(260, 316);
         
        
        //GAME STATE: possible states the game can have
        enum GameState { Start, InGame, GameOver, Help };
        GameState currentGameState = GameState.Start;

        //SCORING: variables and methods
        int currentScore = 0;
        SpriteFont scoreFont;
        public void addtoScore(int val)
        {
            currentScore += val;
        }

        //LIVES: variables and methods
        int lives = 3;
        public int numberlives
        {
            get { return lives; }
            set
            {
                lives = value;
                if (lives == 0)
                {
                    currentGameState = GameState.GameOver;
                    spriteManager.Enabled = false;
                    spriteManager.Visible = false;
                }
            }
        }

        //CONSTRUCTOR: sets up a handler for the system's graphics device, and a content directory 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.IsFullScreen = true;
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;

            Content.RootDirectory = "Content";            
        }

        //INITIALIZE METHOD: instantiates a SpriteManager object to handle all of our sprites
        protected override void Initialize()
        {
            spriteManager = new SpriteManager(this);
            Components.Add(spriteManager);
            spriteManager.Enabled = false;
            spriteManager.Visible = false;

            base.Initialize();
        }

        //LOAD CONTENT METHOD
        protected override void LoadContent()
        {
            //GraphicsDevice gets the type of graphics device being used by the system
            spriteBatch = new SpriteBatch(GraphicsDevice);
            scoreFont = Content.Load<SpriteFont>(@"Fonts\Pericles");
            
            //TILE STUFF
            Texture2D texture;

            //0
            texture = Content.Load<Texture2D>("Tiles/walltile");
            tileTextures.Add(texture);
            //1
            texture = Content.Load<Texture2D>("Tiles/floortile1");
            tileTextures.Add(texture);
            //2
            texture = Content.Load<Texture2D>("Tiles/floortile2");
            tileTextures.Add(texture);
            //3
            texture = Content.Load<Texture2D>("Tiles/floortile3");
            tileTextures.Add(texture);
            //4
            texture = Content.Load<Texture2D>("Tiles/floortile4");
            tileTextures.Add(texture);
            //5
            texture = Content.Load<Texture2D>("Tiles/floortile5");
            tileTextures.Add(texture);
            //6
            texture = Content.Load<Texture2D>("Tiles/jumptile");
            tileTextures.Add(texture);  
            //7
            texture = Content.Load<Texture2D>("Tiles/jumptile2");
            tileTextures.Add(texture);  

  
            //Splash Screens
            startscreen = Content.Load<Texture2D>("Splash Screens/startscreeny");
            slider = Content.Load<Texture2D>("Splash Screens/slider");
            helpscreen = Content.Load<Texture2D>("Splash Screens/helpscreen");
            gameoverscreen = Content.Load<Texture2D>("Splash Screens/gameoverscreen");
            slider2 = Content.Load<Texture2D>("Splash Screens/slider");
        }

        //UNLOAD CONTENT METHOD
        protected override void UnloadContent()
        {}
       
        //UPDATE METHOD: provides two ways of exiting the game, main update
        protected override void Update(GameTime gameTime)
        {
            //KEYBOARD EXIT
            KeyboardState keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.Escape))
                Exit();

            //GAMEPAD EXIT
            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            //Game state check
            switch(currentGameState)
            {
                case GameState.Start:
                    //adjust the slider
                    if (keyboardState.IsKeyDown(Keys.Down) == true)
                    {
                        if (sliderpos.Y == 195)
                            sliderpos.Y += 126;
                    }
                    if(keyboardState.IsKeyDown(Keys.Up) == true)
                    {
                        if (sliderpos.Y == 321)
                            sliderpos.Y -= 126;
                    }
                    //play the game
                    if (keyboardState.IsKeyDown(Keys.Enter) && sliderpos.Y == 195)
                    {
                        currentGameState = GameState.InGame;
                        spriteManager.Enabled = true;
                        spriteManager.Visible = true;
                    }
                    //quit the program
                    else if (keyboardState.IsKeyDown(Keys.Enter) && sliderpos.Y == 321)
                    {
                        Exit();
                    }
                    //go to help
                    else if (keyboardState.IsKeyDown(Keys.H))
                        currentGameState = GameState.Help;                    
                    break;
                case GameState.InGame:               
                    break;
                case GameState.GameOver:
                    //adjust the slider
                    if (keyboardState.IsKeyDown(Keys.Down) == true)
                    {
                        if (slider2pos.Y == 316)
                            slider2pos.Y += 139;
                    }
                    if (keyboardState.IsKeyDown(Keys.Up) == true)
                    {
                        if (slider2pos.Y == 455)
                            slider2pos.Y -= 139;
                    } 
                    //play the game
                    if (keyboardState.IsKeyDown(Keys.Enter) && slider2pos.Y == 316)
                    {
                        currentGameState = GameState.Start;
                        numberlives = 3;
                        Initialize();
                        spriteManager.Enabled = true;
                        spriteManager.Visible = true;
                    }
                    //quit the program
                    else if (keyboardState.IsKeyDown(Keys.Enter) && slider2pos.Y == 455)
                    {
                        Exit();
                    }
                    break;
                case GameState.Help:
                    if (keyboardState.IsKeyDown(Keys.Enter) == true)
                    {
                        currentGameState = GameState.InGame;
                        spriteManager.Enabled = true;
                        spriteManager.Visible = true;
                    }
                    break;                    
            }
            
            //TILE STUFF
            if (bLoc.X < 300)
            {
                boardMove = 0;
            }
            else
            {
                boardMove = (int)bLoc.X - 300;
            }

            if (keyboardState.IsKeyDown(Keys.Left))
            {
                if (bLoc.X >= 300)
                {
                    bLoc.X -= pSpeed.X * (float)gameTime.ElapsedGameTime.TotalSeconds;
                }
                else
                {
                    pLoc.X -= pSpeed.X * (float)gameTime.ElapsedGameTime.TotalSeconds;
                }
            }
            if (keyboardState.IsKeyDown(Keys.Right))
            {
                if (pLoc.X < 300)
                {
                    pLoc.X += pSpeed.X * (float)gameTime.ElapsedGameTime.TotalSeconds;
                }
                else
                {
                    bLoc.X += pSpeed.X * (float)gameTime.ElapsedGameTime.TotalSeconds;
                }
            }
            //Update elapsed Game Time
            myGameTime = gameTime.TotalGameTime;  
            base.Update(gameTime);
        }

        //DRAW METHOD: main draw
        protected override void Draw(GameTime gameTime)
        {
            switch (currentGameState)
            {
                //START GAME
                case GameState.Start:
                    GraphicsDevice.Clear(Color.White);
                    spriteBatch.Begin();
                    spriteBatch.Draw(startscreen, new Rectangle(0, 0, Window.ClientBounds.Width, Window.ClientBounds.Height), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0);                    
                    spriteBatch.Draw(slider, new Rectangle((int)sliderpos.X, (int)sliderpos.Y, 366, 109), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0);
                    spriteBatch.End();
                    break;
                //IN GAME
                case GameState.InGame:
                    GraphicsDevice.Clear(Color.White);                    
                    spriteBatch.Begin();
                    //Drawing fonts
                    spriteBatch.DrawString(scoreFont, "Score: " + currentScore, new Vector2(500, 10), Color.DarkRed, 0, Vector2.Zero, 1, SpriteEffects.None, 10);
                    //Drawing tiles
                    bacMap.Draw1(spriteBatch, tileTextures, 0);
                    obMap.Draw1(spriteBatch, tileTextures, boardMove);
                    obMap.Draw1(spriteBatch, tileTextures, boardMove - 832);
                    miniMap.Draw1(spriteBatch, tileTextures, boardMove / 8);
                    miniMap.Draw1(spriteBatch, tileTextures, (boardMove / 8) - 832 / 8);  
                    //Draw game time 
                    spriteBatch.DrawString(scoreFont, "Time: " + myGameTime.ToString().Substring(0,8), new Vector2(500, 0), Color.Red);
                    spriteBatch.End();
                    break;
                //GAME OVER
                case GameState.GameOver:
                    GraphicsDevice.Clear(Color.White);
                    spriteBatch.Begin();
                    spriteBatch.Draw(gameoverscreen, new Rectangle(0, 0, Window.ClientBounds.Width, Window.ClientBounds.Height), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0);
                    spriteBatch.Draw(slider2, new Rectangle((int)slider2pos.X, (int)slider2pos.Y, 364, 105), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0);
                    spriteBatch.End();
                    break;
                //HELP SCREEN
                case GameState.Help:
                    GraphicsDevice.Clear(Color.White);
                    spriteBatch.Begin();
                    spriteBatch.Draw(helpscreen, new Rectangle(0, 0, Window.ClientBounds.Width, Window.ClientBounds.Height), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 0);
                    spriteBatch.End();
                    break;               
            }
            base.Draw(gameTime);
        }
    }
}